home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / derror / bug2.c next >
C/C++ Source or Header  |  1997-09-09  |  20KB  |  751 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6. #include <stdio.h>
  7. #include <exec/types.h>
  8. #include <proto/exec.h>
  9. #include <proto/dos.h>
  10. #include <dos/dos.h>
  11. #include <dos/dosextens.h>
  12. #include <string.h>
  13. #include <stdlib.h>
  14. #include <clib/exec_protos.h>
  15. #include <lib/rexx.h>
  16.  
  17.  
  18. #include "error_rev.h"
  19.  
  20. #define PORTNAME "DICE_ERROR_PARSER"
  21.  
  22. typedef struct ErrorInfo {
  23.     struct ErrorInfo *next;
  24.     struct ErrorInfo *prev;
  25.     char             line[1];
  26. } EInfo;
  27.  
  28.  
  29. struct FileInfo {
  30.     struct FileInfo *next;
  31.     struct FileInfo *prev;
  32.     char            *dir;
  33.     char            *args;
  34.     struct ErrorInfo base;
  35.     struct ErrorInfo *cur;
  36. };
  37.  
  38. struct FileInfo files;
  39. struct FileInfo *curfile;
  40.  
  41. char *RexxHostName = NULL;  /* no automatic start */
  42.  
  43. #define MAX_FILENAME 1024
  44. char buf[MAX_FILENAME+1];
  45.  
  46. short active;
  47.  
  48. /***********************************************************************************
  49.  * Procedure: AddLine
  50.  * Synopsis:  AddLine(FileInfo *, char *)
  51.  * Purpose:   Adds the line to the current file information.  If there is not enough
  52.  *            memory, it will simply ignore the line silently.
  53.  ***********************************************************************************/
  54. void AddLine(struct FileInfo *fi, char *line)
  55. {
  56.    struct ErrorInfo *ei;
  57.  
  58.    ei = malloc(sizeof(struct ErrorInfo) + strlen(line));
  59.    if (ei)
  60.    {
  61.       ei->prev = fi->base.prev;
  62.       ei->next = fi->base.prev->next;
  63.       fi->base.prev->next = ei;
  64.       fi->base.prev = ei;
  65.    }
  66. }
  67.  
  68. /***********************************************************************************
  69.  * Procedure: NewFI
  70.  * Synopsis:  FileInfo = NewFI(char *dir, char *args)
  71.  * Purpose:   Creates a new file info.  If it is unable to, it returns NULL
  72.  ***********************************************************************************/
  73. struct FileInfo *NewFI(char *dir, char *args)
  74. {
  75.    struct FileInfo *fi;
  76.  
  77.    fi = malloc(sizeof(struct FileInfo));
  78.    if (fi)
  79.    {
  80.       fi->dir = strdup(dir);
  81.       if (fi->dir)
  82.       {
  83.           fi->args = strdup(args);
  84.           if (fi->args)
  85.           {
  86.              fi->prev = files.prev;
  87.              fi->next = files.prev->next;
  88.              files.prev->next = fi;
  89.              files.prev = fi;
  90.  
  91.              fi->base.prev = fi->base.next = &fi->base;
  92.              fi->cur = NULL;
  93.           }
  94.           else
  95.           {
  96.              free(fi->dir);
  97.              free(fi);
  98.              fi = NULL;
  99.           }
  100.       }
  101.       else
  102.       {
  103.          free(fi);
  104.          fi = NULL;
  105.       }
  106.    }
  107.    return(fi);
  108. }
  109.  
  110. /***********************************************************************************
  111.  * Procedure: FreeFI
  112.  * Synopsis:  FreeFI(struct FileInfo *)
  113.  * Purpose:   Removes a FileInfo structure from the list
  114.  ***********************************************************************************/
  115. void FreeFI(struct FileInfo *fi)
  116. {
  117.    struct ErrorInfo *ei;
  118.  
  119.    /* Handle any attempts to free the base FI */
  120.    if (fi == files) return;
  121.  
  122.    /* Unlink us from the chain of file handles */
  123.    fi->prev->next = fi->next;
  124.    fi->next->prev = fi->prev;
  125.  
  126.    /* Update any system pointers which might look at what we are going to free */
  127.    if (curfile == fi)
  128.    {
  129.       curfile = files.next;
  130.       if (curfile == files) curfile = NULL;  // no more anyway
  131.    }
  132.  
  133.    /* Free all the lines */
  134.    fi->base.prev->next == NULL;  // mark our stopping point
  135.    for(ei = fi->base.next; ei != NULL;)
  136.    {
  137.       struct ErrorInfo *sei;
  138.  
  139.       sei = ei;
  140.       ei = ei->next;
  141.       free(sei);
  142.    }
  143.  
  144.    /* Finally, get rid of the file information */
  145.    free(fi->dir);
  146.    free(fi->args);
  147.    free(fi);
  148. }
  149. k
  150. /***********************************************************************************
  151.  * Procedure: say
  152.  * Synopsis:  (void)say(msg);
  153.  * Purpose:   Displays the given message on the console
  154.  ***********************************************************************************/
  155. void say(char *msg)
  156. {
  157.    BPTR out;
  158.    out = Output();
  159.    if (out)
  160.    {
  161.       Write(out, msg, strlen(msg));
  162.       Write(out, "\n", 1);
  163.    }
  164. }
  165.  
  166. /***********************************************************************************
  167.  * Procedure: usage
  168.  * Synopsis:  (void)usage();
  169.  * Purpose:   Displays the command line usage message - does not return
  170.  ***********************************************************************************/
  171. void usage(void)
  172. {
  173.    say("FILE/M,MACRO/K,PROJECT/K" VERSTAG);
  174.    exit(20);
  175. }
  176.  
  177. /***********************************************************************************
  178.  * Procedure: mustmalloc
  179.  * Synopsis:  mem = mustmalloc(size);
  180.  * Purpose:   Allocates memory or Displays an outof memory message -
  181.  *            if there is not enough memory, it does not return
  182.  ***********************************************************************************/
  183. void *mustmalloc(int size)
  184. {
  185.    void *r;
  186.  
  187.    r = malloc(size);
  188.    if (r == NULL)
  189.    {
  190.       say("No Memory!\n");
  191.       exit(20);
  192.    }
  193.    return(r);
  194. }
  195.  
  196. /***********************************************************************************
  197.  * Procedure: dottx
  198.  * Synopsis:  result = dottx(port, cmd);
  199.  * Purpose:   Sends a command to TurboText
  200.  ***********************************************************************************/
  201. char *dottx(char *port, char *cmd)
  202. {
  203.    char *res;
  204.    long ec;
  205.  
  206.    if (port == NULL) port = "TURBOTEXT";
  207.    PlaceRexxCommandDirect(NULL, port, cmd, &res, &ec);
  208.  
  209.    return(res);
  210. }
  211.  
  212. /***********************************************************************************
  213.  * Procedure: full_path
  214.  * Synopsis:  path = full_path(name)
  215.  * Purpose:   Constructs a fully expanded filename
  216.  *            Note, we can not assume that the file exists, so it will not be possible
  217.  *            to actually lock it.  We can assume that the directory it is part of
  218.  *            does exist.
  219.  ***********************************************************************************/
  220. char *full_path(char *name)
  221. {
  222.    BPTR lock;
  223.    __aligned struct FileInfoBlock fib;
  224.    char *tail, *p;
  225.    int pos;
  226.  
  227.    /* Step 1 - split out any directory information from the actual name */
  228.    p = strrchr(name, '/');
  229.    if (p == NULL) p = strrchr(name, ':');
  230.    if (p != NULL)
  231.    {
  232.       /* There was some directory information involved */
  233.       char c;
  234.       tail = strdup(p+1);
  235.       c = p[1];
  236.       p[1] = 0;
  237.       lock = Lock(name, SHARED_LOCK);
  238.       p[1] = c;
  239.    }
  240.    else
  241.    {
  242.       /* No directory information involved, just the name relative to the */
  243.       /* current directory                                                */
  244.       lock = Lock("", SHARED_LOCK);
  245.       tail = strdup(name);
  246.    }
  247.  
  248.    /* Step 2 - we have the lock on the directory and the tail part of the name */
  249.    /* We want to construct a fully qualified path for the directory.           */
  250.    /* If for some reason the lock on the directory returned 0, we want to just */
  251.    /* return the name they gave us to begin with.                              */
  252.    if (lock == 0)
  253.    {
  254.       free(tail);
  255.       return(strdup(name));
  256.    }
  257.  
  258.    /* Step 3 - Fully qualify the directory portion into the buffer */
  259.    if (DOSBase->dl_lib.lib_Version >= 36)
  260.    {
  261.       if (!NameFromLock(lock, buf, MAX_FILENAME))
  262.       {
  263.          /* Either the name is too long or there was something else wrong with */
  264.          /* the file name, just return what they gave us as a start            */
  265.          UnLock(lock);
  266.          free(tail);
  267.          return(strdup(name));
  268.       }
  269.       UnLock(lock);
  270.       pos = 0;
  271.    }
  272.    else
  273.    {
  274.       /* Running under 1.3, we have to do this the old fashion way */
  275.  
  276.       /* Just so we don't have to do any inserts/extra copies, we will work */
  277.       /* from the end of the buffer and insert as we go                     */
  278.       pos = MAX_FILENAME;
  279.       buf[--pos] = 0;
  280.       while(lock != 0)
  281.       {
  282.          BPTR parent;
  283.          int len;
  284.  
  285.          /* Examine the lock to get the name for it */
  286.          Examine(lock, &fib);
  287.  
  288.          /* Find the parent of this directory       */
  289.          parent = ParentDir(lock);
  290.          UnLock(lock);
  291.          lock = parent;
  292.  
  293.          len = strlen(fib.fib_FileName);
  294.          pos -= 1;
  295.  
  296.          if (len > pos)
  297.          {
  298.             /* oops, not enough room, just return the name they gave us */
  299.             UnLock(lock);
  300.             free(tail);
  301.             return(strdup(name));
  302.          }
  303.          buf[pos] = lock ? ':' : '/';
  304.          pos -= len;
  305.          memcpy(buf+pos, fib.fib_FileName, len);
  306.       }
  307.    }
  308.  
  309.    /* We have the path part in the buffer and the name part in the tail */
  310.    /* All that is left is to concatenate them together correctly        */
  311.    {
  312.       int len;
  313.  
  314.       /* Successful, the buf holds the path for the directory.  We will need   */
  315.       /* to add a / to the end if it doesn't end in a colon                    */
  316.       len = strlen(buf+pos);
  317.       if ((buf[pos+len-1] != ':') && (buf[pos+len-1] != '/'))
  318.       {
  319.          buf[pos+len++] = '/';
  320.          buf[pos+len] = 0;
  321.       }
  322.       name = malloc(len+strlen(tail)+1);
  323.       if (name != NULL)
  324.       {
  325.          strcpy(name, buf+pos);
  326.          strcpy(name+len, tail);
  327.       }
  328.    }
  329.    return(name);
  330. }
  331.  
  332. /*
  333.  *  This sets the appropriate AREXX stem variables for the return
  334.  *     FILE:   The name of the file to edit
  335.  *     DIR:    The directory that the file is relative to
  336.  *     LINE:   The line number of the file to go to
  337.  *     COL:    The column number in the file
  338.  *     ERRNO:  The error number
  339.  *     STRING: The error message to be printed out
  340.  */
  341.  
  342. void SetStem(void *rxmsg, char *stem, EInfo *einfo)
  343. {
  344.    char stembuf[40];
  345.    int len;
  346.    char *p;
  347.  
  348.    /* DC1: "fails.c" L:1 C:1 W:68 expected semicolon */
  349.  
  350.    strncat(stembuf, stem, 32);
  351.    stembuf[32] = 0;
  352.    len = strlen(stembuf);
  353.  
  354.    p = stembuf+len;
  355.  
  356.    strcpy(p, ".FILE");
  357.    SetRexxVar(rxmsg, stembuf, "FILENAME", 8);
  358.    strcpy(p, ".DIR");
  359.    SetRexxVar(rxmsg, stembuf, "DIRECTORY/DIR", 13);
  360.    strcpy(p, ".LINE");
  361.    SetRexxVar(rxmsg, stembuf, "12", 2);
  362.    strcpy(p, ".COL");
  363.    SetRexxVar(rxmsg, stembuf, "4", 1);
  364.    strcpy(p, ".ERRNO");
  365.    SetRexxVar(rxmsg, stembuf, "42", 2);
  366.    strcpy(p, ".STRING");
  367.    SetRexxVar(rxmsg, stembuf, "Complete Error Message", 22);
  368. }
  369.  
  370. /*
  371.  *  We handle the following Rexx Commands:
  372.  *     Quit
  373.  *     Next <stem>
  374.  *     First <stem>
  375.  *     Prev <stem>
  376.  *     Clear
  377.  *     TTXSame <file>
  378.  *     Load <error> <dir> <sourcefile> <R0> <R1> <R2> <R3> <R4> <R5> <R6> <R7> <R8> <R9>
  379.  *
  380.  *   Where <stem> Is any valid rexx variable name
  381.  */
  382.  
  383. long
  384. DoRexxCommand(msg, port, arg0, pres)
  385. void *msg;              /*  RexxMsg structure if we need it     */
  386. struct MsgPort *port;   /*  MsgPort structure if we need it     */
  387. char *arg0;     /*  arg0                                */
  388. char **pres;    /*  where to put our result if rc==0    */
  389. {
  390.     int rc;
  391.     char cmd[9];
  392.     int i;
  393.     char *p, *t;
  394.  
  395.     printf("MatchCheck %s vs %s\n", arg0, "pass");
  396.  
  397.     strncpy(cmd, arg0, 8);
  398.     cmd[8] = 0;   // Ensure that the string is properly terminated
  399.     p = strchr(cmd, ' ');
  400.     if (p) *p = 0;
  401.  
  402.     p = arg0+strlen(cmd);
  403.     while (*p == ' ') p++;
  404.  
  405.     if (!stricmp(cmd, "QUIT"))
  406.     {
  407.         active = 0;
  408.         rc = 0;
  409.     }
  410.     else if (!stricmp(cmd, "NEXT"))
  411.     {
  412.        SetStem(msg, p, NULL);
  413.        *pres = "NEXT Command Complete";
  414.        rc = 0;
  415.     }
  416.     else if (!stricmp(cmd, "FIRST"))
  417.     {
  418.        SetStem(msg, p, NULL);
  419.        *pres = "FIRST Command Complete";
  420.        rc = 0;
  421.     }
  422.     else if (!stricmp(cmd, "PREV"))
  423.     {
  424.        SetStem(msg, p, NULL);
  425.        *pres = "PREV Command Complete";
  426.        rc = 0;
  427.     }
  428.     else if (!stricmp(cmd, "CLEAR"))
  429.     {
  430.        *pres = "All Errors Cleared";
  431.        rc = 0;
  432.     }
  433.     else if (!stricmp(cmd, "TTXSAME"))
  434.     {
  435.        *pres = "TTXSAME not activated";
  436.        rc = 0;
  437.     }
  438.     else if (!stricmp(cmd, "LOAD"))
  439.     {
  440.         SetStem(msg, "BASE", NULL);
  441.         *pres = "success!";
  442.         rc = 0;
  443.     }
  444.     else
  445.     {
  446.         *pres = "Command Unknown";
  447.         rc = 5;
  448.     }
  449.     return(rc);
  450. }
  451.  
  452.  
  453. #if 0
  454. Pass  :  DC1, DAS, DCPP, DLINK
  455. File  :  Char *
  456. Dir   :
  457. Line  :  Short
  458. Column:  Short
  459. Type  :  W, E, F
  460. Number:  Char
  461. String:  Char *
  462.  
  463. DC1: "fails.c" L:1 C:1 W:68 expected semicolon
  464. DC1: "fails.c" L:2 C:1 W:68 expected semicolon
  465. DC1: "fails.c" L:4 C:1 W:68 expected semicolon
  466. DC1: "fails.c" L:6 C:1 W:68 expected semicolon
  467. DC1: "fails.c" L:7 C:10 W:68 expected semicolon
  468. DC1: "fails.c" L:7 C:1 W:68 expected semicolon
  469. DC1: "fails.c" L:8 C:1 W:68 expected semicolon
  470. DC1: "fails.c" L:10 C:1 W:68 expected semicolon
  471.  
  472.  
  473. SetRexxVar(pending->rxmsg,stem,file_name, strlen(file_name));
  474.  
  475.  
  476. Configuration Options:
  477.    Edit Command
  478.  
  479. #
  480. #    Quick-Fix Error Handling.  Pops up your editor pointing to any
  481. #    warnings or errors.  Enable with the -R option to DCC.
  482. #
  483. #        port=  never_happen    ;Run REXX script
  484. #        port=  REXX        ;Talk directly to REXX
  485. #        port=  your application ;Talk directly to "your application"
  486.  
  487.  
  488. cmd=
  489. port=
  490. rexxcmd=
  491. linkcmd=
  492. linkport=
  493. linkrexxcmd=
  494.  
  495. #
  496. #
  497. #        %e      Error temporary file name
  498. #        %f      Fully qualified source file name
  499. #        %d      Directory containing the source
  500. #        %n      Filepart of source
  501. #        %c    Current Directory (where DCC was run from)
  502. #        %0-%9    argument from -R0/-R9 DCC option (e.g. -R0 fubar)
  503. #
  504. #    Note: A space is not allowed between the keyword and the =!
  505. #
  506. #cmd=   TTX %e MACRO "DCC:Rexx/ParseError.ttx %f %c %0"
  507. port= DICE_ERROR_PARSER
  508. cmd= Load %e %d %f %0 %1 %2 %3 %4 %5 %6 %7 %8 %9
  509.  
  510.  
  511.  
  512. #include "TTXSame_Rev.h"
  513.  
  514. extern struct Library *RexxSysBase;
  515. extern struct DosLibrary *DOSBase;
  516.  
  517. struct SAVER {
  518.    struct SAVER *next;
  519.    char         *fname;
  520. };
  521.  
  522. char *RexxHostName = NULL;
  523.  
  524.  
  525.  
  526. /***********************************************************************************
  527.  * Procedure: main
  528.  * Synopsis:  rc = main(argc, argv);
  529.  * Purpose:   Main entry point
  530.  ***********************************************************************************/
  531. int ttxmain(int argc, char **argv)
  532. {
  533.    char *res;
  534.    int i;
  535.    char *macro;
  536.    char *project;
  537.    struct SAVER base, *nsaver;
  538.  
  539.    project = NULL;
  540.    macro   = NULL;
  541.  
  542.    if (RexxSysBase == NULL)
  543.    {
  544.       say("Unable to open rexxsyslib.library!");
  545.       exit(20);
  546.    }
  547.  
  548.    CreateDiceRexxPort(NULL, NULL);
  549.  
  550.    nsaver = &base;
  551.    base.next = NULL;
  552.  
  553.    if ((argc == 2) && (!strcmp(argv[1], "?"))) usage();
  554.  
  555.    /* Template for command: */
  556.    /* FILE/M,MACRO/S,PROJECT/S */
  557.    for (i = 1; i < argc; i++)
  558.    {
  559.       if (!stricmp(argv[i], "MACRO"))
  560.       {
  561.          if (++i >= argc) usage();
  562.          if (macro != NULL) usage();
  563.          macro = mustmalloc(strlen(argv[i]) + 16); /* ExecArexxMacro */
  564.          strcpy(macro, "ExecArexxMacro ");
  565.          strcat(macro, argv[i]);
  566.       }
  567.       else if (!stricmp(argv[i], "PROJECT"))
  568.       {
  569.          if (++i >= argc) usage();
  570.          project = argv[i];
  571.       }
  572.       else
  573.       {
  574.          if (!stricmp(argv[i], "FILE"))
  575.          {
  576.             if (++i >= argc) usage();
  577.          }
  578.          nsaver->next = mustmalloc(sizeof(struct SAVER));
  579.          nsaver = nsaver->next;
  580.          nsaver->fname = full_path(argv[i]);
  581.          nsaver->next  = NULL;
  582.       }
  583.    }
  584.  
  585.    /* We have parsed our parameters, now we need to load each of the files */
  586.    /* specified into the editor.  In the process we will have to check for */
  587.    /* Any files in the editor to ensure that they are not already loaded   */
  588.    while((nsaver = base.next) != NULL)
  589.    {
  590.       /* Send the command off to rexx to be processed */
  591.       /* We will wait here until it is complete       */
  592.       res = dottx(NULL, "GETDOCUMENTS");
  593.       if (res != NULL)
  594.       {
  595.          char *p, *t, *fname, *pname;
  596.          int len;
  597.          /* Now we need to go through and figure out all the files that are there */
  598.          fname = res;
  599.          pname = NULL;
  600.          while(*fname)
  601.          {
  602.             if (*fname != '"')
  603.             {
  604.                say("TURBOTEXT Sync Error");
  605.                return(20);
  606.             }
  607.             fname++;
  608.             t = fname;
  609.             len = strlen(t);
  610.             while ((len > 11) && memcmp(t, "\" TURBOTEXT", 11)) /* Bug with no parm */
  611.             {
  612.                char *s;
  613.                s = strchr(t+1, '"');
  614.                if (s == NULL) break;
  615.                len -= (s-t);
  616.                t = s;
  617.             }
  618.             /* At this point, t should be pointing at the " in the name */
  619.             *t = 0;
  620.             /* Now we want to get the portname for the file */
  621.             t += 2;
  622.             pname = t;
  623.             while(*t && (*t != ' ')) t++;
  624.             if (*t) *t++ = 0;
  625.  
  626.             p = dottx(pname, "GetFilePath");
  627.  
  628.             /* If this is the file that we are interested in, drop out of the */
  629.             /* loop and go to work on it in the file                          */
  630.             if ((p != NULL) && !stricmp(nsaver->fname, p))
  631.                break;
  632.  
  633.             /* Advance to let the next stuff work */
  634.             fname = t;
  635.             while(*fname == ' ') fname++;
  636.             pname = NULL;
  637.          }
  638.  
  639.          /* If we got a match, the port will tell us who to talk to */
  640.          if (pname == NULL)
  641.          {
  642.             char *ocmd;
  643.             ocmd = mustmalloc(strlen(nsaver->fname) + 15);  /* OPENDOC NAME */
  644.             strcpy(ocmd, "OPENDOC NAME ");
  645.             strcat(ocmd, nsaver->fname);
  646.             pname = dottx(NULL, ocmd);
  647.             free(ocmd);
  648.          }
  649.          else
  650.          {
  651.             char *p;
  652.             p = dottx(pname, "WINDOW2FRONT");
  653.             if (p != NULL) free(p);
  654.             p = dottx(pname, "SCREEN2FRONT");
  655.             if (p != NULL) free(p);
  656.          }
  657.          {
  658.             char *p;
  659.             p = dottx(pname, "ACTIVATEWINDOW");
  660.             if (p != NULL) free(p);
  661.          }
  662.  
  663.          /* We now have the document open, pname is the port to talk to */
  664.          if (project != NULL)
  665.          {
  666.             char *ocmd;
  667.             /* ExecARexxString call setclip(TTX_TURBOTEXT12,myport.1)   */
  668.             /* 123456789012345678901234567890123           4        5   */
  669.             ocmd = mustmalloc(strlen(project)+strlen(pname)+36);
  670.             strcpy(ocmd, "ExecARexxString call setclip(TTX_");
  671.             strcat(ocmd, pname);
  672.             strcat(ocmd, ",");
  673.             strcat(ocmd, project);
  674.             strcat(ocmd, ")");
  675.             p = dottx(pname, ocmd);
  676.             if (p != NULL) free(p);
  677.             free(ocmd);
  678.          }
  679.  
  680.          /* Next we want to issue the macro command to make it run */
  681.          if (macro != NULL)
  682.          {
  683.             char *p;
  684.             p = dottx(pname, macro);
  685.             if (p != NULL) free(p);
  686.          }
  687.          free(res);
  688.       }
  689.  
  690.       /* Take the entry off the list because we have already processed it */
  691.       base.next = nsaver->next;
  692.       free(nsaver->fname);
  693.       free(nsaver);
  694.    }
  695.    return(0);
  696. }
  697. #endif
  698.  
  699.  
  700. /***********************************************************************************
  701.  * Procedure: main
  702.  * Synopsis:  rc = main(argc, argv);
  703.  * Purpose:   Main entry point
  704.  ***********************************************************************************/
  705. int main(ac, av)
  706. char *av[];
  707. {
  708.  
  709.    /*
  710.     *  DICE automatically opens rexxsyslib.library for us as long
  711.     *  as we reference the base variable (via extern) and not
  712.     *  declare it.  lib/rexx.h does this for us.
  713.     *
  714.     *  However, unlike other autoinits, if DICE is unable to open
  715.     *  the library it does not abort the program, hence the following.
  716.     */
  717.    if (RexxSysBase == NULL)
  718.    {
  719.       say("Unable to open rexxsyslib.library !");
  720.       exit(20);
  721.    }
  722.  
  723.    short r = CreateGlobalDiceRexxPort(NULL, PORTNAME);
  724.    if (r < 0)
  725.    {
  726.       say("AREXX Port " PORTNAME " exists.  DError is already running\n");
  727.       exit(20);
  728.    }
  729.  
  730.    say("Creating port " PORTNAME);
  731.  
  732.    active = 1;
  733.  
  734.    /*
  735.     *  Our main loop executes received commands
  736.     */
  737.  
  738.    while (active)
  739.    {
  740.       long mask = Wait(SIGBREAKF_CTRL_C | (1 << RexxSigBit));
  741.  
  742.       if (mask & SIGBREAKF_CTRL_C)
  743.          break;
  744.  
  745.       if (mask & (1 << RexxSigBit))
  746.           ProcessRexxCommands(NULL);
  747.    }
  748.    say("DError terminating\n");
  749.    return(0);
  750. }
  751.